package com.server;

import com.annnotion.RequestBody;
import com.server.scanner.InvokeHolder;
import com.server.scanner.Invoker;
import com.session.Session;
import com.struct.Request;
import com.struct.Response;
import com.struct.ResponseHeader;
import com.struct.ResultCode;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import org.msgpack.MessagePack;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Administrator on 2016/1/7.
 */
public class ServerHandler extends ChannelHandlerAdapter {

    private Map<String, Boolean> nodeCheck = new ConcurrentHashMap<String, Boolean>();
    private String[] whitekList = { "127.0.0.1", "192.168.1.104" };



    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException {
        Request request = (Request) msg;


        // 如果是握手请求消息，处理，其它消息透传
        if (request.getHeader() == null) {
            ctx.fireChannelRead(msg);
            return;
        }



        Object result = null;
        Response response = new Response();
        ResponseHeader header = new ResponseHeader();
        header.setUri(request.getHeader().getUri());
        try {
            String uri = request.getHeader().getUri();
            Invoker invoker = InvokeHolder.getInvoker(uri);
            Method method = invoker.getMethod();


            Class<?> formClazz = null;
            Parameter[] parameters = method.getParameters();

            Object[] paramValues = new Object[parameters.length];

            for(int i = 0; i< parameters.length; i++){
                Parameter parameter = parameters[i];
                formClazz = parameter.getType();
                if(parameter.isAnnotationPresent(RequestBody.class))
                {
                    MessagePack msgPack = new MessagePack();
                    request.setBody(msgPack.read(request.getBodyBytes(), formClazz));

                    paramValues[i] = request.getBody();
                }
                else if(formClazz.isAssignableFrom(Session.class)){
                    Session session = new Session(ctx.channel());
                    paramValues[i] = session;
                }

            }

            result = invoker.invoke(paramValues);
            header.setStateCode(ResultCode.SUCCESS);
            response.setBody(result);

        }catch (Throwable e){
            header.setStateCode(ResultCode.ERROR);
            response.setBody(e.getMessage());
        }
        response.setHeader(header);

        ctx.writeAndFlush(response);

    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        nodeCheck.remove(ctx.channel().remoteAddress().toString());// 删除缓存
        ctx.close();
        ctx.fireExceptionCaught(cause);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

    }
}
